﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CubaLibreBar.Model.Core.Entities;
using CubaLibreBar.Model.Dados;

namespace CubaLibreBar.Win
{
    public partial class CadastroProduto : UserControl
    {
        public CadastroProduto()
        {
            InitializeComponent();
        }

        #region Propriedades

        Produtos ProdutoSelecionado;

        #endregion

        #region Eventos

        /// <summary>
        /// Evento de Load da Tela de Cadastro de Produtos
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CadastroProduto_Load(object sender, EventArgs e)
        {
            txtNomeProduto.Focus(); // foca no primeiro campo
            CarregaGridProdutos(false);
        }

        /// <summary>
        /// Evento de Click do botão Cadastrar da tela de Cadastro de Produtos
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCadastrarProduto_Click(object sender, EventArgs e)
        {
            try
            {
                bool camposValidos = ValidaCampos();

                if (camposValidos)
                {
                    Produtos produto = new Produtos();
                    produto.NomeProduto = txtNomeProduto.Text;
                    produto.QuantidadeProduto = Convert.ToInt32(txtQuantidadeProduto.Text);
                    produto.PrecoCompra = Convert.ToDecimal(txtPrecoCompra.Text.Replace(".", ","));
                    produto.PrecoVenda = Convert.ToDecimal(txtPrecoVenda.Text.Replace(".", ","));

                    ProdutosDAO.CreateProduto(produto);

                    LimpaCampos();
                    btnCancelarPesquisa_Click(btnCancelarPesquisa, new EventArgs());
                    CarregaGridProdutos(false);

                    MessageBox.Show(this, "Produto cadastrado com sucesso.", "CubaLibreBar", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    MessageBox.Show(this, "Verifique os campos indicados com erro e insira valores válidos.", "CubaLibreBar", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception)
            {
                MessageBox.Show(this,
                    "Erro ao tentar converter os dados preenchidos.\nPor favor verifique se os dados informados estão corretos.\n\nO campo Quantidade só aceita números.\nOs campos Preço Compra e Venda use a vírgula ou ponto para separar os centavos dos reais.",
                    "CubaLibreBar", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Salva a edição de um produto
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSalvarProduto_Click(object sender, EventArgs e)
        {
            try
            {
                bool camposValidos = ValidaCampos();

                if (camposValidos)
                {
                ProdutoSelecionado.NomeProduto = txtNomeProduto.Text;
                ProdutoSelecionado.QuantidadeProduto = Convert.ToInt32(txtQuantidadeProduto.Text);
                ProdutoSelecionado.PrecoCompra = Convert.ToDecimal(txtPrecoCompra.Text);
                ProdutoSelecionado.PrecoVenda = Convert.ToDecimal(txtPrecoVenda.Text);

                ProdutosDAO.UpdateProduto(ProdutoSelecionado);

                btnCadastrarProduto.Visible =
                    btnLimpar.Visible = true;

                btnSalvarProduto.Visible =
                    btnCancelar.Visible = false;

                CarregaGridProdutos(true);
                gbFiltros.Enabled = true;
                LimpaCampos();

                MessageBox.Show(this, "Produto atualizado com sucesso.", "CubaLibreBar", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    MessageBox.Show(this, "Verifique os campos indicados com erro e insira valores válidos.", "CubaLibreBar", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception)
            {
                MessageBox.Show(Properties.Resources.ErroConsultaDados);
            }
        }

        /// <summary>
        /// Cancela a edição de um produto
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCancelar_Click(object sender, EventArgs e)
        {
            btnCadastrarProduto.Visible =
                btnLimpar.Visible = true;

            btnSalvarProduto.Visible =
                btnCancelar.Visible = false;

            gbFiltros.Enabled = true;
            LimpaCampos();
        }

        /// <summary>
        /// Limpa os campos da tela
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnLimpar_Click(object sender, EventArgs e)
        {
            LimpaCampos();
        }

        private void txtNomeProduto_KeyPress(object sender, KeyPressEventArgs e)
        {
            epNomeProduto.Clear();
        }

        private void txtPrecoCompra_KeyPress(object sender, KeyPressEventArgs e)
        {
            epPrecoCompra.Clear(); // limpa o ícone de erro

            if (!char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar) && e.KeyChar != '.' && e.KeyChar != ',')
            {
                e.Handled = true;
            }
            else
            {
                e.Handled = false;
            }
        }

        private void txtPrecoVenda_KeyPress(object sender, KeyPressEventArgs e)
        {
            epPrecoVenda.Clear(); // limpa o ícone de erro

            if (!char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar) && e.KeyChar != '.' && e.KeyChar != ',')
            {
                e.Handled = true;
            }
            else
            {
                e.Handled = false;
            }
        }

        private void txtQuantidadeProduto_KeyPress(object sender, KeyPressEventArgs e)
        {
            epQuantidade.Clear(); // limpa o ícone de erro

            if (char.IsDigit(e.KeyChar) || char.IsControl(e.KeyChar))
            {
                e.Handled = false;
            }
            else
            {
                e.Handled = true;
            }
        }

        private void txtFiltroCodigo_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (char.IsDigit(e.KeyChar) || char.IsControl(e.KeyChar))
            {
                e.Handled = false;
            }
            else
            {
                e.Handled = true;
            }
        }

        private void grvProdutos_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex < 0 || e.RowIndex < 0) return; // header clicked

            if (e.ColumnIndex == grvProdutos.Columns["btnDelete"].Index)
            {
                if (btnCancelar.Visible == true)
                    btnCancelar_Click(btnCancelar, new EventArgs());

                int idProduto = Convert.ToInt32(grvProdutos["IdProduto", e.RowIndex].Value);

                ProdutoSelecionado = ProdutosDAO.GetById(idProduto);

                DialogResult resultado = MessageBox.Show("Deseja deletar o produto " + ProdutoSelecionado.NomeProduto
                    , "Delete", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);

                if (resultado.Equals(DialogResult.OK))
                {
                    try
                    {
                        ProdutosDAO.DeleteProduto(idProduto);

                        LimpaCampos();
                        CarregaGridProdutos(false);

                        MessageBox.Show(this, "Produto excluído com sucesso.", "CubaLibreBar", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception ex)
                    {
                        if(ex.Message.Contains("FK_Produtos_VendasProdutos"))
                            MessageBox.Show(this, "Esse produto não pode ser excluído porque possui vendas registradas.", "CubaLibreBar", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                        else
                            MessageBox.Show(this, Properties.Resources.ErroConsultaDados, "CubaLibreBar", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }

            if (e.ColumnIndex == grvProdutos.Columns["btnEdit"].Index)
            {
                LimpaCampos();
                gbFiltros.Enabled = false;

                int idProduto = Convert.ToInt32(grvProdutos["IdProduto", e.RowIndex].Value);

                ProdutoSelecionado = ProdutosDAO.GetById(idProduto);

                txtNomeProduto.Text = ProdutoSelecionado.NomeProduto;
                txtQuantidadeProduto.Text = ProdutoSelecionado.QuantidadeProduto.ToString();
                txtPrecoCompra.Text = ProdutoSelecionado.PrecoCompra.ToString();
                txtPrecoVenda.Text = ProdutoSelecionado.PrecoVenda.ToString();

                btnCadastrarProduto.Visible =
                    btnLimpar.Visible = false;

                btnSalvarProduto.Visible =
                    btnCancelar.Visible = true;
            }
        }

        private void grvProdutos_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
            grvProdutos.ClearSelection();
        }

        private void btnPesquisar_Click(object sender, EventArgs e)
        {
            CarregaGridProdutos(true);
        }

        private void btnCancelarPesquisa_Click(object sender, EventArgs e)
        {
            LimparPesquisa();
            CarregaGridProdutos(false);
        }

        private void LimparPesquisa()
        {
            txtFiltroCodigo.Text =
                txtFiltroNomeProduto.Text = string.Empty;

            btnCancelarPesquisa.Visible = false;
        }
        
        #endregion

        #region Métodos

        /// <summary>
        /// Carrega todos os produtos cadastrados na DataGridView de Produtos
        /// </summary>
        private void CarregaGridProdutos(bool isPesquisa)
        {
            try
            {
                // botao editar
                if (!grvProdutos.Columns.Contains("btnEdit"))
                {
                    DataGridViewImageColumn btnEditarLinha = new DataGridViewImageColumn();
                    btnEditarLinha.HeaderText = "Editar";
                    btnEditarLinha.Name = "btnEdit";
                    btnEditarLinha.Width = 20;
                    btnEditarLinha.Image = Properties.Resources.EditImage;
                    grvProdutos.Columns.Add(btnEditarLinha);
                }

                // botao deletar
                if (!grvProdutos.Columns.Contains("btnDelete"))
                {
                    DataGridViewImageColumn btnDeleteLinha = new DataGridViewImageColumn();
                    btnDeleteLinha.HeaderText = "Excluir";
                    btnDeleteLinha.Name = "btnDelete";
                    btnDeleteLinha.Width = 20;
                    btnDeleteLinha.Image = Properties.Resources.DeleteImage;
                    grvProdutos.Columns.Add(btnDeleteLinha);
                }

                // Carrega os dados dos produtos
                if (isPesquisa)
                {
                    int? idProduto = null;
                    string nomeProduto = null;

                    if (String.IsNullOrEmpty(txtFiltroCodigo.Text))
                        idProduto = null;
                    else
                        idProduto = Convert.ToInt32(txtFiltroCodigo.Text);

                    if (String.IsNullOrEmpty(txtFiltroNomeProduto.Text))
                        nomeProduto = null;
                    else
                        nomeProduto = txtFiltroNomeProduto.Text;

                    if (idProduto == null && nomeProduto == null)
                        btnCancelarPesquisa.Visible = false;
                    else
                        btnCancelarPesquisa.Visible = true;

                    grvProdutos.DataSource = ProdutosDAO.GetAllProdutosWithWhere(idProduto, nomeProduto);
                }
                else
                    grvProdutos.DataSource = ProdutosDAO.GetAllProdutos();
                
                // Troca os nomes das colunas da GridView
                grvProdutos.Columns["IdProduto"].HeaderText = "Código";
                grvProdutos.Columns["NomeProduto"].HeaderText = "Produto";
                grvProdutos.Columns["QuantidadeProduto"].HeaderText = "Quantidade";
                grvProdutos.Columns["PrecoCompra"].HeaderText = "Preço de Compra";
                grvProdutos.Columns["PrecoVenda"].HeaderText = "Preço de Venda";

                // selecionar a linha inteira
                grvProdutos.SelectionMode = DataGridViewSelectionMode.FullRowSelect;

                // alinhamento das colunas
                grvProdutos.Columns["NomeProduto"].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
                grvProdutos.ColumnHeadersDefaultCellStyle.Font = new Font("Arial", 10, FontStyle.Bold);
                grvProdutos.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.BottomCenter;
                grvProdutos.DefaultCellStyle.Alignment = DataGridViewContentAlignment.BottomCenter;
                grvProdutos.DefaultCellStyle.Font = new Font("Arial", 10, FontStyle.Regular);

                // Formato de Dinheiro
                grvProdutos.Columns["PrecoCompra"].DefaultCellStyle.Format = "C";
                grvProdutos.Columns["PrecoVenda"].DefaultCellStyle.Format = "C";                
            }
            catch (Exception)
            {
                MessageBox.Show(Properties.Resources.ErroConsultaDados);
            }
        }

        /// <summary>
        /// Limpa todos os campos da tela de cadastro de produtos
        /// </summary>
        public void LimpaCampos()
        {
            txtNomeProduto.Text =
                txtQuantidadeProduto.Text =
                    txtPrecoCompra.Text =
                        txtPrecoVenda.Text = string.Empty;

            epNomeProduto.Clear();
            epQuantidade.Clear();
            epPrecoCompra.Clear();
            epPrecoVenda.Clear();

            txtNomeProduto.Focus();
        }

        #endregion

        #region Validações

        //********************************************************************************************************************************
        /// <summary>
        /// Usa os métodos de validação e valida todo o formulário
        /// </summary>
        /// <returns></returns>
        private bool ValidaCampos()
        {
            bool nomeProduto = ValidaNomeProduto();
            bool quantidade = ValidaQuantidade();
            bool precoVenda = ValidaPrecoVenda();
            bool precoCompra = ValidaPrecoCompra();

            if (!nomeProduto)
                txtNomeProduto.Focus();
            else if (!quantidade)
                txtQuantidadeProduto.Focus();
            else if (!precoVenda)
                txtPrecoVenda.Focus();
            else if (!precoCompra)
                txtPrecoCompra.Focus();

            return nomeProduto && quantidade && precoVenda && precoCompra;
        }
        //********************************************************************************************************************************
        /// <summary>
        /// Método que válida o campo NomeProduto
        /// </summary>
        /// <returns>retorna true se for válido e false se for inválido</returns>
        private bool ValidaNomeProduto()
        {
            bool valido = false;

            if (txtNomeProduto.Text == string.Empty)
            {
                epNomeProduto.SetError(txtNomeProduto, "O campo Nome Produto é obrigatório.");
            }
            else if (txtNomeProduto.Text.Length > 99)
            {
                epNomeProduto.SetError(txtNomeProduto, "O campo Nome Produto não pode ser maior que 99 caracteres.");
                txtNomeProduto.Text = string.Empty;
            }
            else
            {
                epNomeProduto.Clear();
                valido = true;
            }

            return valido;
        }
        //********************************************************************************************************************************
        /// <summary>
        /// Método que válida o campo Quantidade
        /// </summary>
        /// <returns>retorna true se for válido e false se for inválido</returns>
        private bool ValidaQuantidade()
        {
            bool valido = false;
            int res;

            if (txtQuantidadeProduto.Text == string.Empty)
            {
                epQuantidade.SetError(txtQuantidadeProduto, "O campo Quantidade é obrigatório.");
            }
            else if (!Int32.TryParse(txtQuantidadeProduto.Text, out res))
            {
                epQuantidade.SetError(txtQuantidadeProduto, "O campo Quantidade deve ser preenchido apenas com números.");
                txtQuantidadeProduto.Text = string.Empty;
            }
            else
            {
                epQuantidade.Clear();
                valido = true;
            }

            return valido;
        }
        //********************************************************************************************************************************
        /// <summary>
        /// Método que válida o campo PrecoCompra
        /// </summary>
        /// <returns>retorna true se for válido e false se for inválido</returns>
        private bool ValidaPrecoCompra()
        {
            bool valido = false;
            decimal res;

            if (txtPrecoCompra.Text == string.Empty)
            {
                epPrecoCompra.SetError(txtPrecoCompra, "O campo Preço de Compra é obrigatório.");
            }
            else if (!Decimal.TryParse(txtPrecoCompra.Text, out res))
            {
                epPrecoCompra.SetError(txtPrecoCompra, "O campo Preço de Compra deve ser preenchido apenas com números e vírgula (,) ou ponto (.) para separar os reais dos centavos.");
                txtPrecoCompra.Text = string.Empty;
            }
            else
            {
                epPrecoCompra.Clear();
                valido = true;
            }

            return valido;
        }
        //********************************************************************************************************************************
        /// <summary>
        /// Método que válida o campo PrecoVenda
        /// </summary>
        /// <returns>retorna true se for válido e false se for inválido</returns>
        private bool ValidaPrecoVenda()
        {
            bool valido = false;
            decimal res;

            if (txtPrecoVenda.Text == string.Empty)
            {
                epPrecoVenda.SetError(txtPrecoVenda, "O campo Preço de Venda é obrigatório.");
            }
            if (!Decimal.TryParse(txtPrecoVenda.Text, out res))
            {
                epPrecoVenda.SetError(txtPrecoVenda, "O campo Preço de Venda deve ser preenchido apenas com números e vírgula (,) ou ponto (.) para separar os reais dos centavos.");
                txtPrecoVenda.Text = string.Empty;
            }
            else
            {
                epPrecoVenda.Clear();
                valido = true;
            }

            return valido;
        }

        #endregion

    }
}
